#pragma once
#include <string>
/*
* 1. "世" 的 UTF-8 编码在内存中的存储
  汉字"世"的 UTF-8 编码确实是 0xE4 0xB8 0x96.
  在 x64 Linux(小端序系统)上, 它们会按照写入的顺序存储
      低内存地址 -> 高内存地址
      0xE4 | 0xB8 | 0x96

  这是因为 UTF-8 是一种单字节编码, 每个字节都是独立的实体. 字节序问题只影响多字节数据类型(如 short, int, wchar_t 等)的存储方式, 而不影响字节序列的顺序
  所以, std::mbtowc 函数会按顺序读取这三个字节 0xE4, 0xB8, 0x96, 然后将它们解码为对应的 Unicode 码点.

  2. std::mbtowc 转换后的结果
  std::mbtowc 会将 UTF-8 序列 0xE4 0xB8 0x96 转换为 Unicode 码点 U+4E16.

  在 Linux 上, wchar_t 通常是 4 字节(32 位), 用于表示 UTF-32 编码. 所以转换后的结果是一个 32 位整数 0x00004E16.
    UTF-32 采用了一种最直接, 最简单的编码方式.
    规则: 每一个 Unicode 码点都直接用 1 个 32 位(4 字节) 的整数来存储.
    映射关系: 码点的值就是 UTF-32 的值.
        U+4E16 -> 直接存储为 32 位整数 0x00004E16
    优点: 固定长度, 处理简单, 因为每个字符都用同样大小的空间.
    缺点: 非常浪费空间, 因为大部分常用字符的码点都很小(U+0000 到 U+FFFF), 前两个字节总是 0x00.
    这就引入了字节序(Endianness)问题:
    这个 32 位的整数 0x00004E16 在内存或文件里怎么存?
        UTF-32BE (Big-Endian): 高位字节在前 -> 00 00 4E 16
        UTF-32LE (Little-Endian): 低位字节在前 -> 16 4E 00 00
    所以, UTF-32LE/BE 就是规定了 UTF-32 这种编码方式的字节存储顺序.
    UTF-16 是一种可变长度编码, 它更聪明, 也更复杂一些. 同样存在UTF-16BE/LE

  由于 x64 Linux 是小端序系统, 这个值在内存中的存储方式是:
      低内存地址 -> 高内存地址
      0x16 | 0x4E | 0x00 | 0x00
 */
#include "ZiFuScreenZhanWeiJiSuan.h"
using namespace std;
class TabToSpace
{
    string out;
    string in;
public:
    TabToSpace(string in) : in(std::move(in)){}
    string&& TabToSpace_Main()
    {
        std::setlocale(LC_ALL, "");
        const char* move_ptr = in.c_str();
        const char* end = move_ptr + in.size();

        int display_width{0};
        int space_add_num{0};
        while (move_ptr < end)
        {
            wchar_t wc = L'\0';
            int bytes = std::mbtowc(&wc, move_ptr, in.size());

            if (bytes <= 0) {
                // 无效序列，跳过1字节
                move_ptr++;
                continue;
            }

            // ASCII字符
            if (bytes == 1) {
                if (wc == '\n')
                {
                    move_ptr++;
                    display_width = 0;
                    out += wc;
                    continue;
                }
                if (wc == '\t')
                {
                    switch ((display_width + 1) % 4)
                    {
                    case 1:
                        display_width += 4;
                        space_add_num = 4;
                        break;
                    case 2:
                        display_width += 3;
                        space_add_num = 3;
                        break;
                    case 3:
                        display_width += 2;
                        space_add_num = 2;
                        break;
                    case 0:
                        display_width += 1;
                        space_add_num = 1;
                        break;
                    default:
                        throw std::logic_error("制表符占位计算逻辑错误!");
                    }
                    for (int i = 0; i < space_add_num; i++)
                    {
                        out += " ";
                    }
                    move_ptr++;
                    continue;
                }
                else
                {
                    display_width += 1;
                    // out += wc;
                }
            }
            // 宽字符（汉字或全角字符）
            else if (ZiFuScreenZhanWeiJiSuan::is_wide_character(wc)) {
                display_width += 2;
                // out += wc;
            }
            // 其他多字节字符
            else {
                display_width += 1;
                // out += wc;
            }
            ZiFuScreenZhanWeiJiSuan::append_wide_char_simple(out ,wc);
            for (int i = 0; i<bytes; i++)
            {
                ++move_ptr;
            }
        }
        return std::move(out);
    }
};

